package com.kovidinvo.domofon

import com.fasterxml.jackson.databind.ObjectMapper
import jakarta.websocket.Encoder.Text
import org.springframework.context.annotation.Configuration
import org.springframework.stereotype.Component
import org.springframework.web.socket.CloseStatus
import org.springframework.web.socket.TextMessage
import org.springframework.web.socket.WebSocketHandler
import org.springframework.web.socket.WebSocketSession
import org.springframework.web.socket.config.annotation.EnableWebSocket
import org.springframework.web.socket.config.annotation.WebSocketConfigurer
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry
import org.springframework.web.socket.handler.TextWebSocketHandler


@Configuration
@EnableWebSocket
class WebSocketConfig : WebSocketConfigurer {
    override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
        registry.addHandler(SignalSocketHandler(),"/signals").setAllowedOrigins("*")
    }
}

data class Message(val from:String,val to:String,val type:String,val data:String)


@Component
class SignalSocketHandler : TextWebSocketHandler() {

    val clients = emptyList<String>()
    val mapper = ObjectMapper()
    //val sessions = mutableListOf<WebSocketSession>()
    val sessions = mutableMapOf<String,WebSocketSession>()

    override fun afterConnectionEstablished(session: WebSocketSession) {
        sessions[session.id] = session
        val msg = mapper.writeValueAsString(Message("server","client","approved",session.id))
        session.sendMessage(TextMessage(msg))
        sendClients()
    }

    fun sendClients() {
        val ids = sessions.keys.toList()
        val ds = mapper.writeValueAsString(ids)
        sessions.values.forEach { sess ->
            val msg = mapper.writeValueAsString(Message("server",sess.id,"clients",ds))
            sess.sendMessage(TextMessage(msg))
        }
    }

    override fun afterConnectionClosed(session: WebSocketSession, status: CloseStatus) {
        sessions.remove(session.id)
        sendClients()
    }

    override fun handleTextMessage(session: WebSocketSession, message: TextMessage) {
        val msg = mapper.readValue(message.payload,Message::class.java)
        val ses = sessions[msg.to]?: return
        ses.sendMessage(message)
        //sessions.filter { sess -> sess.isOpen && sess.id!=session.id }.forEach { sess -> sess.sendMessage(message) }
    }
}